﻿using System;
using System.Collections.Generic;
#if !NOEXPRESSION
using System.Linq.Expressions;
#endif
using MugenInjection.Activators;
using MugenInjection.Bindings;
using MugenInjection.Bindings.Builders;
using MugenInjection.Delegates;
using MugenInjection.Infrastructure;
using MugenInjection.Interception.Interface;
using MugenInjection.Interception.Interface.Components;
using MugenInjection.Interception.Syntax;
using MugenInjection.Interface;
using MugenInjection.Scope;
using MugenInjection.Syntax.Constant;
using MugenInjection.Syntax.Method;
using MugenInjection.Syntax.Type;

namespace MugenInjection.Interception.Bindings.Builders
{
    internal class InterceptorBindingBuilder<T> :
        IInterceptAsTargetConstantSyntax,
        IInterceptAsTargetMethodSyntax,
        IInterceptAsTargetTypeSyntax,
        IInterceptAsTargetConstantSyntax<T>,
        IInterceptAsTargetMethodSyntax<T>,
        IInterceptAsTargetTypeSyntax<T>,
        IInterceptTypeSyntax,
        IInterceptTypeSyntax<T>
    {
        #region Fields

        private readonly IBinding _proxyBinding;
        private readonly IList<IInterceptorProcess> _interceptorProcesses;
        private readonly IBindingBuilder _bindingBuilder;


        private readonly ITypeCallbackConstructorObjectPriorityScopeUseWhenWithSyntax _typeSyntax;
        private readonly ITypeCallbackObjectUseWithSyntax _typeObjectSyntax;
        private readonly IConstantObjectSyntax _constantObjectSyntax;
        private readonly IMethodCallbackObjectUseWithSyntax _methodObjectSyntax;

        private readonly ITypeCallbackConstructorObjectPriorityScopeUseWhenWithSyntax<T> _typeSyntaxGeneric;
        private readonly ITypeCallbackObjectUseWithSyntax<T> _typeObjectSyntaxGeneric;
        private readonly IConstantObjectSyntax<T> _constantObjectSyntaxGeneric;
        private readonly IMethodCallbackObjectUseWithSyntax<T> _methodObjectSyntaxGeneric;
        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="InterceptorBindingBuilder{T}"/> class.
        /// </summary>
        private InterceptorBindingBuilder(IBindingBuilder bindingBuilder,
                                          IList<IInterceptorProcess> interceptorProcesses)
        {
            Validate.ArgumentNotNull(bindingBuilder, "bindingBuilder");
            Validate.ArgumentNotNull(interceptorProcesses, "interceptorProcesses");
            _bindingBuilder = bindingBuilder;
            _interceptorProcesses = interceptorProcesses;
            Builded += BuildInternal;
            /*//Replace builder.
            _bindingBuilder.Settings[BindingBuilderConfigurator.BuilderKey] = this;*/
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InterceptorBindingBuilder{T}"/> class.
        /// </summary>
        internal InterceptorBindingBuilder(IBinding proxyBinding, IBindingBuilder bindingBuilder,
                                         IList<IInterceptorProcess> interceptorProcesses)
            : this(bindingBuilder, interceptorProcesses)
        {
            Validate.ArgumentNotNull(proxyBinding, "proxyBinding");
            _proxyBinding = proxyBinding;
            _constantObjectSyntax = bindingBuilder as IConstantObjectSyntax;
            _methodObjectSyntax = bindingBuilder as IMethodCallbackObjectUseWithSyntax;
            _typeObjectSyntax = bindingBuilder as ITypeCallbackObjectUseWithSyntax;
            _constantObjectSyntaxGeneric = bindingBuilder as IConstantObjectSyntax<T>;
            _methodObjectSyntaxGeneric = bindingBuilder as IMethodCallbackObjectUseWithSyntax<T>;
            _typeObjectSyntaxGeneric = bindingBuilder as ITypeCallbackObjectUseWithSyntax<T>;
            if (_constantObjectSyntax == null && _methodObjectSyntax == null && _typeObjectSyntax == null
                && _constantObjectSyntaxGeneric == null && _methodObjectSyntaxGeneric == null && _typeObjectSyntaxGeneric == null)
                throw new NotSupportedException(string.Format("The type {0} is not supported by the InterceptorBuilder.",
                                                              bindingBuilder.GetType()));
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InterceptorBindingBuilder{T}"/> class.
        /// </summary>
        internal InterceptorBindingBuilder(ITypeCallbackConstructorObjectPriorityScopeUseWhenWithSyntax typeSyntax,
                                         IList<IInterceptorProcess> interceptorProcesses)
            : this(bindingBuilder: typeSyntax, interceptorProcesses: interceptorProcesses)
        {
            _typeSyntax = typeSyntax;
            _typeObjectSyntax = (ITypeCallbackObjectUseWithSyntax)typeSyntax;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InterceptorBindingBuilder{T}"/> class.
        /// </summary>
        internal InterceptorBindingBuilder(ITypeCallbackConstructorObjectPriorityScopeUseWhenWithSyntax<T> typeSyntaxGeneric,
                                         IList<IInterceptorProcess> interceptorProcesses)
            : this(bindingBuilder: typeSyntaxGeneric, interceptorProcesses: interceptorProcesses)
        {
            _typeSyntaxGeneric = typeSyntaxGeneric;
            _typeObjectSyntaxGeneric = (ITypeCallbackObjectUseWithSyntax<T>)typeSyntaxGeneric;
        }

        #endregion

        #region Methods

        private void ReplaceActivator()
        {
            Func<IActivator> defaultActivator;
            if (!Settings.TryGet(BindingBuilderConfigurator.ActivatorFuncKey, out defaultActivator))
                defaultActivator = Injector.Settings.DefaultActivatorFactory;
            IActivator activator = defaultActivator();
            defaultActivator = () => new InterceptorActivator(activator);
            Settings[BindingBuilderConfigurator.ActivatorFuncKey] = defaultActivator;
        }

        private IBinding BuildInternal(IBindingBuilder builder)
        {
            Validate.ArgumentNotNull(builder, "builder");
            var component = Injector.Components.Get<IInterceptionManagerComponent>();
            ISimpleInterceptorProcess simpleInterceptor;
            Settings.TryGet(InterceptionExtensionUtils.AdditionalInterceptorKey, out simpleInterceptor);
            IBinding binding;
            IBinding bindingToAdd;
            if (_typeSyntax != null)
            {
                ReplaceActivator();
                binding = builder.Build();
                bindingToAdd = binding;
            }
            else
            {
                IBinding build = builder.Build();
                binding = new InterceptorBinding(build, _proxyBinding);
                bindingToAdd = _proxyBinding;
            }
            if (simpleInterceptor != null)
                component.AddInterceptorProcess(bindingToAdd, new SimpleInterceptorProcessAdapter(simpleInterceptor));
            for (int index = 0; index < _interceptorProcesses.Count; index++)
            {
                var interceptorProcess = _interceptorProcesses[index];
                component.AddInterceptorProcess(bindingToAdd, interceptorProcess);
            }
            return binding;
        }

        #endregion

        #region Implementation of IBindingBuilder

        /// <summary>
        /// Gets the <see cref="IInjector"/> that owns the <see cref="IBindingBuilder"/>.
        /// </summary>
        public IInjector Injector
        {
            get { return _bindingBuilder.Injector; }
        }

        /// <summary>
        /// Gets the specified service types. 
        /// </summary>
        public IList<Type> Services
        {
            get { return _bindingBuilder.Services; }
        }

        /// <summary>
        /// Gets the settings for the current <see cref="IBindingBuilder"/>.
        /// </summary>
        public ISettings Settings
        {
            get { return _bindingBuilder.Settings; }
        }

        /// <summary>
        ///     Indicates that the binding builder is configuring.
        /// </summary>
        public bool IsConfiguring
        {
            get { return _bindingBuilder.IsConfiguring; }
        }

        public event BindingBuildingDelegate Building
        {
            add { _bindingBuilder.Building += value; }
            remove { _bindingBuilder.Building -= value; }
        }

        public event BindingBuildedDelegate Builded
        {
            add { _bindingBuilder.Builded += value; }
            remove { _bindingBuilder.Builded -= value; }
        }

        /// <summary>
        /// Builds the current <see cref="IBindingBuilder"/>.
        /// </summary>
        /// <returns>The builded <see cref="IBinding"/>.</returns>
        IBinding IBindingBuilder.Build()
        {
            return _bindingBuilder.Build();
        }

        #endregion

        #region Implementation of IConstantObjectSyntax

        /// <summary>
        /// Try to dispose the object after binding disposed.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IConstantObjectSyntax IConstantObjectSyntax.TryDisposeObjects()
        {
            Validate.NotSupportedIfNull(_constantObjectSyntax);
            _constantObjectSyntax.TryDisposeObjects();
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be registered with the specified name. Names are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same name.
        /// </summary>
        /// <param name="name">The name to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        IConstantObjectSyntax IConstantObjectSyntax.NamedBinding(string name)
        {
            Validate.NotSupportedIfNull(_constantObjectSyntax);
            _constantObjectSyntax.NamedBinding(name);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be registered with the specified key. Keys are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same key.
        /// </summary>
        /// <param name="key">The key to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        IConstantObjectSyntax IConstantObjectSyntax.KeyedBinding(object key)
        {
            Validate.NotSupportedIfNull(_constantObjectSyntax);
            _constantObjectSyntax.KeyedBinding(key);
            return this;
        }

        /// <summary>
        /// The specified setting for build binding.
        /// </summary>
        /// <param name="key">Setting name.</param>
        /// <param name="value">Setting value.</param>
        /// <returns>The fluent syntax.</returns>
        IConstantObjectSyntax IConstantObjectSyntax.WithSetting(string key, object value)
        {
            Validate.NotSupportedIfNull(_constantObjectSyntax);
            _constantObjectSyntax.WithSetting(key, value);
            return this;
        }

        #endregion

        #region Implementation of IConstantObjectSyntax<T>

        /// <summary>
        /// Try to dispose the object after binding disposed.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IConstantObjectSyntax<T> IConstantObjectSyntax<T>.TryDisposeObjects()
        {
            Validate.NotSupportedIfNull(_constantObjectSyntaxGeneric);
            _constantObjectSyntaxGeneric.TryDisposeObjects();
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be registered with the specified name. Names are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same name.
        /// </summary>
        /// <param name="name">The name to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        IConstantObjectSyntax<T> IConstantObjectSyntax<T>.NamedBinding(string name)
        {
            Validate.NotSupportedIfNull(_constantObjectSyntaxGeneric);
            _constantObjectSyntaxGeneric.NamedBinding(name);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be registered with the specified key. Keys are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same key.
        /// </summary>
        /// <param name="key">The key to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        IConstantObjectSyntax<T> IConstantObjectSyntax<T>.KeyedBinding(object key)
        {
            Validate.NotSupportedIfNull(_constantObjectSyntaxGeneric);
            _constantObjectSyntaxGeneric.KeyedBinding(key);
            return this;
        }

        /// <summary>
        /// The specified setting for build binding.
        /// </summary>
        /// <param name="key">Setting name.</param>
        /// <param name="value">Setting value.</param>
        /// <returns>The fluent syntax.</returns>
        IConstantObjectSyntax<T> IConstantObjectSyntax<T>.WithSetting(string key, object value)
        {
            Validate.NotSupportedIfNull(_constantObjectSyntaxGeneric);
            _constantObjectSyntaxGeneric.WithSetting(key, value);
            return this;
        }

        #endregion

        #region Implementation of IMethodObjectSyntax

        /// <summary>
        /// Indicates that the binding should be registered with the specified name. Names are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same name.
        /// </summary>
        /// <param name="name">The name to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodObjectSyntax.NamedBinding(string name)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.NamedBinding(name);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be registered with the specified key. Keys are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same key.
        /// </summary>
        /// <param name="key">The key to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodObjectSyntax.KeyedBinding(object key)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.KeyedBinding(key);
            return this;
        }

        /// <summary>
        /// The specified setting for build binding.
        /// </summary>
        /// <param name="key">Setting name.</param>
        /// <param name="value">Setting value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodObjectSyntax.WithSetting(string key, object value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.WithSetting(key, value);
            return this;
        }

        /// <summary>
        /// Try to dispose the object after binding disposed.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodObjectSyntax.TryDisposeObjects()
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.TryDisposeObjects();
            return this;
        }

        #endregion

        #region Implementation of IMethodObjectSyntax<T>

        /// <summary>
        /// Indicates that the binding should be registered with the specified name. Names are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same name.
        /// </summary>
        /// <param name="name">The name to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodObjectSyntax<T>.NamedBinding(string name)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.NamedBinding(name);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be registered with the specified key. Keys are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same key.
        /// </summary>
        /// <param name="key">The key to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodObjectSyntax<T>.KeyedBinding(object key)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.KeyedBinding(key);
            return this;
        }

        /// <summary>
        /// The specified setting for build binding.
        /// </summary>
        /// <param name="key">Setting name.</param>
        /// <param name="value">Setting value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodObjectSyntax<T>.WithSetting(string key, object value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithSetting(key, value);
            return this;
        }

        /// <summary>
        /// Try to dispose the object after binding disposed.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodObjectSyntax<T>.TryDisposeObjects()
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.TryDisposeObjects();
            return this;
        }

        #endregion

        #region Implementation of IMethodCallbackSyntax

        /// <summary>
        ///     Indicates that the binding should executes callback method after binding activated.
        /// </summary>
        /// <param name="onActivated">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodCallbackSyntax.OnActivated(Action<object> onActivated)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.OnActivated(onActivated);
            return this;
        }

        /// <summary>
        /// Execute callback method after binding activated.
        /// </summary>
        /// <param name="onActivated">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodCallbackSyntax.OnActivated(BindingActivatedDelegate<object> onActivated)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.OnActivated(onActivated);
            return this;
        }

        /// <summary>
        /// Execute callback method after binding disposed.
        /// </summary>
        /// <param name="onDisposed">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodCallbackSyntax.OnDisposed(Action<IBinding> onDisposed)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.OnDisposed(onDisposed);
            return this;
        }

        /// <summary>
        ///     Executes the callback that should be called before instances are released.
        /// </summary>
        /// <param name="onReleaseObject">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodCallbackSyntax.OnReleaseObject(Action<object, bool> onReleaseObject)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.OnReleaseObject(onReleaseObject);
            return this;
        }

        /// <summary>
        /// Execute callback method before binding activated.
        /// </summary>
        /// <param name="onActivating">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodCallbackSyntax.OnActivating(Action<IBindingContext> onActivating)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.OnActivating(onActivating);
            return this;
        }

        #endregion

        #region Implementation of IMethodCallbackSyntax<T>

        /// <summary>
        ///     Indicates that the binding should executes callback method after binding activated.
        /// </summary>
        /// <param name="onActivated">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodCallbackSyntax<T>.OnActivated(Action<T> onActivated)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.OnActivated(onActivated);
            return this;
        }

        /// <summary>
        /// Execute callback method after binding activated.
        /// </summary>
        /// <param name="onActivated">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodCallbackSyntax<T>.OnActivated(BindingActivatedDelegate<T> onActivated)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.OnActivated(onActivated);
            return this;
        }

        /// <summary>
        /// Execute callback method after binding disposed.
        /// </summary>
        /// <param name="onDisposed">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodCallbackSyntax<T>.OnDisposed(Action<IBinding> onDisposed)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.OnDisposed(onDisposed);
            return this;
        }

        /// <summary>
        ///     Executes the callback that should be called before instances are released.
        /// </summary>
        /// <param name="onReleaseObject">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodCallbackSyntax<T>.OnReleaseObject(Action<T, bool> onReleaseObject)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.OnReleaseObject(onReleaseObject);
            return this;
        }

        /// <summary>
        /// Execute callback method before binding activated.
        /// </summary>
        /// <param name="onActivating">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodCallbackSyntax<T>.OnActivating(Action<IBindingContext> onActivating)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.OnActivating(onActivating);
            return this;
        }

        #endregion

        #region Implementation of IMethodUseSyntax

        /// <summary>
        /// Use emit activator for activate instance.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodUseSyntax.UseEmitActivator()
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.UseEmitActivator();
            return this;
        }

#if !NOEXPRESSION
        /// <summary>
        /// Use expression activator for activate instance.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodUseSyntax.UseExpressionActivator()
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.UseExpressionActivator();
            return this;
        }
#endif
        /// <summary>
        /// Use custom activator for activate instance.
        /// </summary>
        /// <param name="activator">The specified <see cref="IActivator"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodUseSyntax.UseCustomActivator(IActivator activator)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.UseCustomActivator(activator);
            return this;
        }

        /// <summary>
        /// Use custom activator for activate instance.
        /// </summary>
        /// <param name="methodActivator">The specified <see cref="Func{TResult}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodUseSyntax.UseCustomActivator(Func<IActivator> methodActivator)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.UseCustomActivator(methodActivator);
            return this;
        }

        /// <summary>
        /// Use reflection activator for activate instance.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodUseSyntax.UseReflectionActivator()
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.UseReflectionActivator();
            return this;
        }

        #endregion

        #region Implementation of IMethodUseSyntax<T>

        /// <summary>
        /// Use emit activator for activate instance.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodUseSyntax<T>.UseEmitActivator()
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.UseEmitActivator();
            return this;
        }

        /// <summary>
        /// Use custom activator for activate instance.
        /// </summary>
        /// <param name="activator">The specified <see cref="IActivator"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodUseSyntax<T>.UseCustomActivator(IActivator activator)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.UseCustomActivator(activator);
            return this;
        }

#if !NOEXPRESSION
        /// <summary>
        /// Use expression activator for activate instance.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodUseSyntax<T>.UseExpressionActivator()
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.UseExpressionActivator();
            return this;
        }
#endif
        /// <summary>
        /// Use custom activator for activate instance.
        /// </summary>
        /// <param name="methodActivator">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodUseSyntax<T>.UseCustomActivator(Func<IActivator> methodActivator)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.UseCustomActivator(methodActivator);
            return this;
        }

        /// <summary>
        /// Use reflection activator for activate instance.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodUseSyntax<T>.UseReflectionActivator()
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.UseReflectionActivator();
            return this;
        }

        #endregion

        #region Implementation of IMethodWithSyntax

        /// <summary>
        /// Use specified constructor argument.
        /// </summary>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodWithSyntax.WithConstructorArgument(string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.WithConstructorArgument(name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified method argument.
        /// </summary>
        /// <param name="methodName">The specified method name.</param>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="value">The specified parameter value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodWithSyntax.WithMethodArgument(string methodName, string name, object value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.WithMethodArgument(methodName, name, value);
            return this;
        }

        /// <summary>
        /// Use specified method argument.
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodWithSyntax.WithMethodArgument(string methodName, string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.WithMethodArgument(methodName, name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="name">The specified property name.</param>
        /// <param name="value">The specified property value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodWithSyntax.WithPropertyValue(string name, object value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.WithPropertyValue(name, value);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="name">The specified property name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodWithSyntax.WithPropertyValue(string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.WithPropertyValue(name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified custom argument.
        /// </summary>
        /// <param name="parameter">The specified <see cref="IInjectionParameter"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodWithSyntax.WithParameter(IInjectionParameter parameter)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.WithParameter(parameter);
            return this;
        }

        /// <summary>
        /// Use specified constructor argument.
        /// </summary>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="value">The specified parameter value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax IMethodWithSyntax.WithConstructorArgument(string name, object value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntax);
            _methodObjectSyntax.WithConstructorArgument(name, value);
            return this;
        }

        #endregion

        #region Implementation of IMethodWithSyntax<T>

#if NOEXPRESSION
        /// <summary>
        /// Use specified constructor argument.
        /// </summary>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithConstructorArgument(string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithConstructorArgument(name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified method argument.
        /// </summary>
        /// <param name="methodName">The specified method name.</param>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="value">The specified parameter value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithMethodArgument(string methodName, string name, object value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithMethodArgument(methodName, name, value);
            return this;
        }

        /// <summary>
        /// Use specified method argument.
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithMethodArgument(string methodName, string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithMethodArgument(methodName, name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="name">The specified property name.</param>
        /// <param name="value">The specified property value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithPropertyValue(string name, object value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithPropertyValue(name, value);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="name">The specified property name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithPropertyValue(string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithPropertyValue(name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified constructor argument.
        /// </summary>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="value">The specified parameter value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithConstructorArgument(string name, object value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithConstructorArgument(name, value);
            return this;
        }
#else
        /// <summary>
        /// Use specified method arguments.
        /// </summary>
        /// <param name="methodCall">The specified method call expression.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithMethodArguments(Expression<Action<ResolveContext, T>> methodCall)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithMethodArguments(methodCall);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="property">The property accesss expression.</param>
        /// <param name="value">The specified property value.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithPropertyValue<TValue>(Expression<Func<T, TValue>> property, TValue value)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithPropertyValue(property, value);
            return this;
        }

        /// <summary>
        /// Indicates that the service should be use specified method arguments.
        /// </summary>
        /// <param name="constructorCall">The specified new instance expression.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithConstructorArguments(Expression<Func<ResolveContext, T>> constructorCall)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithConstructorArguments(constructorCall);
            return this;
        }
#endif
        /// <summary>
        /// Use specified custom argument.
        /// </summary>
        /// <param name="parameter">The specified <see cref="IInjectionParameter"/>.</param>
        /// <returns>The fluent syntax.</returns>
        IMethodCallbackObjectUseWithSyntax<T> IMethodWithSyntax<T>.WithParameter(IInjectionParameter parameter)
        {
            Validate.NotSupportedIfNull(_methodObjectSyntaxGeneric);
            _methodObjectSyntaxGeneric.WithParameter(parameter);
            return this;
        }
        #endregion

        #region Implementation of ITypeObjectSyntax

        /// <summary>
        /// Indicates that the binding should be registered with the specified name. Names are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same name.
        /// </summary>
        /// <param name="name">The name to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeObjectSyntax.NamedBinding(string name)
        {
            Validate.NotSupportedIfNull(_typeObjectSyntax);
            _typeObjectSyntax.NamedBinding(name);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be registered with the specified key. Keys are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same key.
        /// </summary>
        /// <param name="key">The key to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeObjectSyntax.KeyedBinding(object key)
        {
            Validate.NotSupportedIfNull(_typeObjectSyntax);
            _typeObjectSyntax.KeyedBinding(key);
            return this;
        }
        
        /// <summary>
        /// The specified setting for build binding.
        /// </summary>
        /// <param name="key">Setting name.</param>
        /// <param name="value">Setting value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeObjectSyntax.WithSetting(string key, object value)
        {
            Validate.NotSupportedIfNull(_typeObjectSyntax);
            _typeObjectSyntax.WithSetting(key, value);
            return this;
        }

        /// <summary>
        /// Try to dispose the object after binding disposed.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeObjectSyntax.TryDisposeObjects()
        {
            Validate.NotSupportedIfNull(_typeObjectSyntax);
            _typeObjectSyntax.TryDisposeObjects();
            return this;
        }

        #endregion

        #region Implementation of ITypeObjectSyntax<T>

        /// <summary>
        /// Indicates that the binding should be registered with the specified name. Names are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same name.
        /// </summary>
        /// <param name="name">The name to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeObjectSyntax<T>.NamedBinding(string name)
        {
            Validate.NotSupportedIfNull(_typeObjectSyntaxGeneric);
            _typeObjectSyntaxGeneric.NamedBinding(name);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be registered with the specified key. Keys are not
        /// necessarily unique; multiple bindings for a given service may be registered with the same key.
        /// </summary>
        /// <param name="key">The key to give the binding.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeObjectSyntax<T>.KeyedBinding(object key)
        {
            Validate.NotSupportedIfNull(_typeObjectSyntaxGeneric);
            _typeObjectSyntaxGeneric.KeyedBinding(key);
            return this;
        }

        /// <summary>
        /// The specified setting for build binding.
        /// </summary>
        /// <param name="key">Setting name.</param>
        /// <param name="value">Setting value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeObjectSyntax<T>.WithSetting(string key, object value)
        {
            Validate.NotSupportedIfNull(_typeObjectSyntaxGeneric);
            _typeObjectSyntaxGeneric.WithSetting(key, value);
            return this;
        }

        /// <summary>
        /// Try to dispose the object after binding disposed.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeObjectSyntax<T>.TryDisposeObjects()
        {
            Validate.NotSupportedIfNull(_typeObjectSyntaxGeneric);
            _typeObjectSyntaxGeneric.TryDisposeObjects();
            return this;
        }

        #endregion

        #region Implementation of ITypeCallbackSyntax

        /// <summary>
        /// Execute callback method before binding activated.
        /// </summary>
        /// <param name="onActivating">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeCallbackSyntax.OnActivating(Action<IBindingContext> onActivating)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.OnActivating(onActivating);
            return this;
        }

        /// <summary>
        ///     Indicates that the binding should executes callback method after binding activated.
        /// </summary>
        /// <param name="onActivated">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeCallbackSyntax.OnActivated(Action<object> onActivated)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.OnActivated(onActivated);
            return this;
        }

        /// <summary>
        /// Execute callback method after binding activated.
        /// </summary>
        /// <param name="onActivated">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeCallbackSyntax.OnActivated(BindingActivatedDelegate<object> onActivated)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.OnActivated(onActivated);
            return this;
        }

        /// <summary>
        ///     Executes the callback that should be called before instances are released.
        /// </summary>
        /// <param name="onReleaseObject">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeCallbackSyntax.OnReleaseObject(Action<object, bool> onReleaseObject)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.OnReleaseObject(onReleaseObject);
            return this;
        }

        /// <summary>
        /// Execute callback method after binding disposed.
        /// </summary>
        /// <param name="onDisposed">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeCallbackSyntax.OnDisposed(Action<IBinding> onDisposed)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.OnDisposed(onDisposed);
            return this;
        }

        #endregion

        #region Implementation of ITypeCallbackSyntax<T>

        /// <summary>
        /// Execute callback method after binding activated.
        /// </summary>
        /// <param name="onActivated">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeCallbackSyntax<T>.OnActivated(BindingActivatedDelegate<T> onActivated)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.OnActivated(onActivated);
            return this;
        }

        /// <summary>
        ///     Indicates that the binding should executes callback method after binding activated.
        /// </summary>
        /// <param name="onActivated">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeCallbackSyntax<T>.OnActivated(Action<T> onActivated)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.OnActivated(onActivated);
            return this;
        }

        /// <summary>
        /// Execute callback method after binding disposed.
        /// </summary>
        /// <param name="onDisposed">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeCallbackSyntax<T>.OnDisposed(Action<IBinding> onDisposed)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.OnDisposed(onDisposed);
            return this;
        }

        /// <summary>
        ///     Executes the callback that should be called before instances are released.
        /// </summary>
        /// <param name="onReleaseObject">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeCallbackSyntax<T>.OnReleaseObject(Action<T, bool> onReleaseObject)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.OnReleaseObject(onReleaseObject);
            return this;
        }

        /// <summary>
        /// Execute callback method before binding activated.
        /// </summary>
        /// <param name="onActivating">The specified callback method.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeCallbackSyntax<T>.OnActivating(Action<IBindingContext> onActivating)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.OnActivating(onActivating);
            return this;
        }

        #endregion

        #region Implementation of ITypeConstructorSyntax

        /// <summary>
        /// Indicates that the service should be bound to the specified constructor.
        /// </summary>
        /// <param name="types">The specified parameters for search constructor.</param>
        /// <returns>The fluent syntax.</returns>
        public ITypeCallbackObjectPriorityUseWithSyntax TakeConstructor(params Type[] types)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            Validate.ArgumentNotNull(types, "types");
            types = InterceptionExtensionUtils
                .GetInterceptionManagerComponent(_typeSyntax.Injector)
                .ProxyFactory.ProxyBuilder.GetProxyConstructorTypes(types);
            _typeSyntax.TakeConstructor(types);
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the speecified constructor.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax ITypeConstructorSyntax.TakeConstructor<T1>()
        {
            TakeConstructor(new[] { typeof(T1) });
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the speecified constructor.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax ITypeConstructorSyntax.TakeConstructor<T1, T2>()
        {
            TakeConstructor(new[] { typeof(T1), typeof(T2) });
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the speecified constructor.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="T3"></typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax ITypeConstructorSyntax.TakeConstructor<T1, T2, T3>()
        {
            TakeConstructor(new[] { typeof(T1), typeof(T2), typeof(T3) });
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the speecified constructor.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="T3"></typeparam>
        /// <typeparam name="T4"></typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax ITypeConstructorSyntax.TakeConstructor<T1, T2, T3, T4>()
        {
            TakeConstructor(new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) });
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the speecified constructor.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="T3"></typeparam>
        /// <typeparam name="T4"></typeparam>
        /// <typeparam name="T5"></typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax ITypeConstructorSyntax.TakeConstructor<T1, T2, T3, T4, T5>()
        {
            TakeConstructor(new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) });
            return this;
        }

        #endregion

        #region Implementation of ITypeConstructorSyntax<T>

#if NOEXPRESSION
        /// <summary>
        /// Indicates that the service should be bound to the specified constructor.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax<T> ITypeConstructorSyntax<T>.TakeConstructor<T1>()
        {
            ((ITypeConstructorSyntax<T>)this).TakeConstructor(new[] { typeof(T1) });
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the specified constructor.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax<T> ITypeConstructorSyntax<T>.TakeConstructor<T1, T2>()
        {
            ((ITypeConstructorSyntax<T>)this).TakeConstructor(new[] { typeof(T1), typeof(T2) });
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the specified constructor.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax<T> ITypeConstructorSyntax<T>.TakeConstructor<T1, T2, T3>()
        {
            ((ITypeConstructorSyntax<T>)this).TakeConstructor(new[] { typeof(T1), typeof(T2), typeof(T3) });
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the specified constructor.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax<T> ITypeConstructorSyntax<T>.TakeConstructor<T1, T2, T3, T4>()
        {
            ((ITypeConstructorSyntax<T>)this).TakeConstructor(new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) });
            return this;
        }

        /// <summary>
        /// Indicates that the service should be bound to the specified constructor.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax<T> ITypeConstructorSyntax<T>.TakeConstructor<T1, T2, T3, T4, T5>()
        {
            ((ITypeConstructorSyntax<T>)this).TakeConstructor(new[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) });
            return this;
        }

#else
        /// <summary>
        /// Use specified constructor.
        /// </summary>
        /// <param name="constructor">The constructor expression.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax<T> ITypeConstructorSyntax<T>.TakeConstructor(Expression<Func<ResolveContext, T>> constructor)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            var newExpression = InjectorUtilsInternal.ParseNewExpression(constructor);
            var parameterInfos = newExpression.Constructor.GetParameters();
            var types = new Type[parameterInfos.Length];
            for (int index = 0; index < parameterInfos.Length; index++)
            {
                var parameterInfo = parameterInfos[index];
                types[index] = parameterInfo.ParameterType;
            }
            ((ITypeConstructorSyntax<T>)this).TakeConstructor(types);
            return this;
        }
#endif

        /// <summary>
        /// Indicates that the service should be bound to the specified constructor.
        /// </summary>
        /// <param name="types">The specified parameters for search constructor.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectPriorityUseWithSyntax<T> ITypeConstructorSyntax<T>.TakeConstructor(Type[] types)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            Validate.ArgumentNotNull(types, "types");
            types = InterceptionExtensionUtils
                .GetInterceptionManagerComponent(_typeSyntaxGeneric.Injector)
                .ProxyFactory.ProxyBuilder.GetProxyConstructorTypes(types);
            _typeSyntaxGeneric.TakeConstructor(types);
            return this;
        }

        #endregion

        #region Implementation of ITypePrioritySyntax

        /// <summary>
        /// Manual set priority for binding.
        /// </summary>
        /// <param name="priority">The specified <see cref="BindingPriority"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypePrioritySyntax.SetPriority(BindingPriority priority)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.SetPriority(priority);
            return this;
        }

        /// <summary>
        /// Set standard priority for binding.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypePrioritySyntax.SetStandardPriority()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.SetStandardPriority();
            return this;
        }

        /// <summary>
        /// Set low priority for binding.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypePrioritySyntax.SetLowPriority()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.SetLowPriority();
            return this;
        }

        /// <summary>
        /// Set normal priority for binding.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypePrioritySyntax.SetNormalPriority()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.SetNormalPriority();
            return this;
        }

        /// <summary>
        /// Set high priority for binding.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypePrioritySyntax.SetHighPriority()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.SetHighPriority();
            return this;
        }

        #endregion

        #region Implementation of ITypePrioritySyntax<T>

        /// <summary>
        /// Set standard priority for binding.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypePrioritySyntax<T>.SetStandardPriority()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.SetStandardPriority();
            return this;
        }

        /// <summary>
        /// Set low priority for binding.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypePrioritySyntax<T>.SetLowPriority()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.SetLowPriority();
            return this;
        }

        /// <summary>
        /// Set normal priority for binding.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypePrioritySyntax<T>.SetNormalPriority()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.SetNormalPriority();
            return this;
        }

        /// <summary>
        /// Set high priority for binding.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypePrioritySyntax<T>.SetHighPriority()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.SetHighPriority();
            return this;
        }

        /// <summary>
        /// Manual set priority for binding.
        /// </summary>
        /// <param name="priority">The specified <see cref="BindingPriority"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypePrioritySyntax<T>.SetPriority(BindingPriority priority)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.SetPriority(priority);
            return this;
        }

        #endregion

        #region Implementation of ITypeScopeSyntax

        /// <summary>
        ///  Indicates that instances activated via the custom lifecycle managment.
        /// </summary>
        /// <param name="customScopeDelegate">The specified <see cref="CustomScopeDelegate"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax ITypeScopeSyntax.InScope(
            CustomScopeDelegate customScopeDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.InScope(customScopeDelegate);
            return this;
        }

        /// <summary>
        ///  Indicates that instances activated via the specified lifecycle
        /// </summary>
        /// <param name="scopeLifecycle">The specified <see cref="IScopeLifecycle"/>. </param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax ITypeScopeSyntax.InScope(IScopeLifecycle scopeLifecycle)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.InScope(scopeLifecycle);
            return this;
        }

        /// <summary>
        /// Indicates that only a single instance of the binding should be created, and then
        /// should be re-used for all subsequent requests.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax ITypeScopeSyntax.InSingletonScope()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.InSingletonScope();
            return this;
        }

        /// <summary>
        /// Indicates that instances activated via the binding should be re-used within the same thread.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax ITypeScopeSyntax.InThreadScope()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.InThreadScope();
            return this;
        }

        /// <summary>
        /// Indicates that instances activated via the binding should not be re-used, nor have their lifecycle managed.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax ITypeScopeSyntax.InTransientScope()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.InTransientScope();
            return this;
        }

        /// <summary>
        /// Indicates that only a single instance of the binding should be created in each <see cref="IInjector"/>, and then
        /// should be re-used for all subsequent requests. 
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax ITypeScopeSyntax.InUnitOfWorkScope()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.InUnitOfWorkScope();
            return this;
        }

        /// <summary>
        ///  Indicates that instances activated via the <see cref="IManagedScope"/> lifecycle managment.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax ITypeScopeSyntax.InManagedScope()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.InManagedScope();
            return this;
        }

        /// <summary>
        /// Indicates that instances activated via the binding should be re-used as weak reference.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax ITypeScopeSyntax.InWeakReferenceScope()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.InWeakReferenceScope();
            return this;
        }

        #endregion

        #region  Implementation of ITypeScopeSyntax<T>

        /// <summary>
        ///  Indicates that instances activated via the specified lifecycle
        /// </summary>
        /// <param name="scopeLifecycle">The specified <see cref="IScopeLifecycle"/>. </param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax<T> ITypeScopeSyntax<T>.InScope(IScopeLifecycle scopeLifecycle)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.InScope(scopeLifecycle);
            return this;
        }

        /// <summary>
        /// Indicates that only a single instance of the binding should be created, and then
        /// should be re-used for all subsequent requests.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax<T> ITypeScopeSyntax<T>.InSingletonScope()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.InSingletonScope();
            return this;
        }

        /// <summary>
        /// Indicates that instances activated via the binding should be re-used within the same thread.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax<T> ITypeScopeSyntax<T>.InThreadScope()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.InThreadScope();
            return this;
        }

        /// <summary>
        /// Indicates that instances activated via the binding should not be re-used, nor have their lifecycle managed.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax<T> ITypeScopeSyntax<T>.InTransientScope()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.InTransientScope();
            return this;
        }

        /// <summary>
        /// Indicates that only a single instance of the binding should be created in each <see cref="IInjector"/>, and then
        /// should be re-used for all subsequent requests. 
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax<T> ITypeScopeSyntax<T>.InUnitOfWorkScope()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.InUnitOfWorkScope();
            return this;
        }

        /// <summary>
        ///  Indicates that instances activated via the <see cref="IManagedScope"/> lifecycle managment.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax<T> ITypeScopeSyntax<T>.InManagedScope()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.InManagedScope();
            return this;
        }

        /// <summary>
        ///  Indicates that instances activated via the custom lifecycle managment.
        /// </summary>
        /// <param name="customScopeDelegate">The specified <see cref="CustomScopeDelegate"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax<T> ITypeScopeSyntax<T>.InScope(CustomScopeDelegate customScopeDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.InScope(customScopeDelegate);
            return this;
        }

        /// <summary>
        /// Indicates that instances activated via the binding should be re-used as weak reference.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityUseWithSyntax<T> ITypeScopeSyntax<T>.InWeakReferenceScope()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.InWeakReferenceScope();
            return this;
        }

        #endregion

        #region Implementation of ITypeUseSyntax

        /// <summary>
        /// Use reflection activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeUseSyntax.UseReflectionActivator()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.UseReflectionActivator();
            return this;
        }

        /// <summary>
        /// Use emit activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeUseSyntax.UseEmitActivator()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.UseEmitActivator();
            return this;
        }

#if !NET2
        /// <summary>
        /// Use expression activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeUseSyntax.UseExpressionActivator()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.UseExpressionActivator();
            return this;
        }
#endif

        /// <summary>
        /// Use custom activator for create new instance of object.
        /// </summary>
        /// <param name="activator">The specified <see cref="IActivator"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeUseSyntax.UseCustomActivator(IActivator activator)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.UseCustomActivator(activator);
            return this;
        }

        /// <summary>
        /// Use custom activator for create new instance of object.
        /// </summary>
        /// <param name="methodActivator">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeUseSyntax.UseCustomActivator(Func<IActivator> methodActivator)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.UseCustomActivator(methodActivator);
            return this;
        }

        /// <summary>
        /// Use custom constructor resolver for select constructor for specified service.
        /// </summary>
        /// <param name="constructorResolver">The specified <see cref="IConstructorResolver"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeUseSyntax.UseCustomConstructorResolver(
            IConstructorResolver constructorResolver)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.UseCustomConstructorResolver(constructorResolver);
            return this;
        }

        /// <summary>
        /// Use custom constructor resolver for select constructor for specified service.
        /// </summary>
        /// <param name="constructorResolver">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeUseSyntax.UseCustomConstructorResolver(
            Func<IConstructorResolver> constructorResolver)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.UseCustomConstructorResolver(constructorResolver);
            return this;
        }

        #endregion

        #region Implementation of ITypeUseSyntax<T>

        /// <summary>
        /// Use emit activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeUseSyntax<T>.UseEmitActivator()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.UseEmitActivator();
            return this;
        }

#if !NOEXPRESSION
        /// <summary>
        /// Use expression activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeUseSyntax<T>.UseExpressionActivator()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.UseExpressionActivator();
            return this;
        }
#endif

        /// <summary>
        /// Use custom activator for create new instance of object.
        /// </summary>
        /// <param name="activator">The specified <see cref="IActivator"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeUseSyntax<T>.UseCustomActivator(IActivator activator)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.UseCustomActivator(activator);
            return this;
        }

        /// <summary>
        /// Use custom activator for create new instance of object.
        /// </summary>
        /// <param name="methodActivator">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeUseSyntax<T>.UseCustomActivator(Func<IActivator> methodActivator)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.UseCustomActivator(methodActivator);
            return this;
        }

        /// <summary>
        /// Use custom constructor resolver for select constructor for specified service.
        /// </summary>
        /// <param name="constructorResolver">The specified <see cref="IConstructorResolver"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeUseSyntax<T>.UseCustomConstructorResolver(IConstructorResolver constructorResolver)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.UseCustomConstructorResolver(constructorResolver);
            return this;
        }

        /// <summary>
        /// Use custom constructor resolver for select constructor for specified service.
        /// </summary>
        /// <param name="constructorResolver">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeUseSyntax<T>.UseCustomConstructorResolver(Func<IConstructorResolver> constructorResolver)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.UseCustomConstructorResolver(constructorResolver);
            return this;
        }

        /// <summary>
        /// Use reflection activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeUseSyntax<T>.UseReflectionActivator()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.UseReflectionActivator();
            return this;
        }

        #endregion

        #region Implementation of ITypeWhenSyntax

        /// <summary>
        /// Indicates that the binding should be used only for requests that support the specified condition.
        /// </summary>
        /// <param name="canResolveBindingDelegate">The specified <see cref="CanResolveBindingDelegate"/></param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax ITypeWhenSyntax.When(
            CanResolveBindingDelegate canResolveBindingDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.When(canResolveBindingDelegate);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type.
        /// Types that derive from the specified type will not be considered as valid target.
        /// </summary>
        /// <param name="type">The type of target.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax ITypeWhenSyntax.WhenInto(Type type)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WhenInto(type);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type <see cref="TType"/>.
        /// Types that derive from the specified type will not be considered as valid target.
        /// </summary>
        /// <typeparam name="TType">The type of target.</typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax ITypeWhenSyntax.WhenInto<TType>()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WhenInto<TType>();
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type.
        /// Types that derive from the specified type are considered as valid targets.
        /// </summary>
        /// <param name="type">The type of target.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax ITypeWhenSyntax.WhenIntoIsAssignable(Type type)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WhenIntoIsAssignable(type);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type <see cref="TType"/>.
        /// Types that derive from the specified type are considered as valid targets.
        /// </summary>
        /// <typeparam name="TType">The type of target.</typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax ITypeWhenSyntax.WhenIntoIsAssignable<TType>()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WhenIntoIsAssignable<TType>();
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type when namespace equals.
        /// </summary>
        /// <param name="name">The name of namespace.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax ITypeWhenSyntax.WhenNamespaceEqual(string name)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WhenNamespaceEqual(name);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only when the class being injected has
        /// an attribute of the specified type.
        /// </summary>
        /// <param name="attributeType">The type of attribute.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax ITypeWhenSyntax.WhenClassHasAttribute(
            Type attributeType)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WhenClassHasAttribute(attributeType);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only when the class being injected has
        /// an attribute of the specified type.
        /// </summary>
        /// <typeparam name="TAttribute">The type of attribute.</typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax ITypeWhenSyntax.WhenClassHasAttribute<TAttribute>()
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WhenClassHasAttribute<TAttribute>();
            return this;
        }

        #endregion

        #region Implementation of ITypeWhenSyntax<T>

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type.
        /// Types that derive from the specified type will not be considered as valid target.
        /// </summary>
        /// <param name="type">The type of target.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax<T> ITypeWhenSyntax<T>.WhenInto(Type type)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WhenInto(type);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type <see cref="TType"/>.
        /// Types that derive from the specified type will not be considered as valid target.
        /// </summary>
        /// <typeparam name="TType">The type of target.</typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax<T> ITypeWhenSyntax<T>.WhenInto<TType>()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WhenInto<TType>();
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type.
        /// Types that derive from the specified type are considered as valid targets.
        /// </summary>
        /// <param name="type">The type of target.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax<T> ITypeWhenSyntax<T>.WhenIntoIsAssignable(Type type)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WhenIntoIsAssignable(type);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type <see cref="TType"/>.
        /// Types that derive from the specified type are considered as valid targets.
        /// </summary>
        /// <typeparam name="TType">The type of target.</typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax<T> ITypeWhenSyntax<T>.WhenIntoIsAssignable<TType>()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WhenIntoIsAssignable<TType>();
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for injections on the specified type when namespace equals.
        /// </summary>
        /// <param name="name">The name of namespace.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax<T> ITypeWhenSyntax<T>.WhenNamespaceEqual(string name)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WhenNamespaceEqual(name);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only when the class being injected has
        /// an attribute of the specified type.
        /// </summary>
        /// <param name="attributeType">The type of attribute.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax<T> ITypeWhenSyntax<T>.WhenClassHasAttribute(Type attributeType)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WhenClassHasAttribute(attributeType);
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only when the class being injected has
        /// an attribute of the specified type.
        /// </summary>
        /// <typeparam name="TAttribute">The type of attribute.</typeparam>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax<T> ITypeWhenSyntax<T>.WhenClassHasAttribute<TAttribute>()
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WhenClassHasAttribute<TAttribute>();
            return this;
        }

        /// <summary>
        /// Indicates that the binding should be used only for requests that support the specified condition.
        /// </summary>
        /// <param name="canResolveBindingDelegate">The specified <see cref="CanResolveBindingDelegate"/></param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackConstructorObjectPriorityScopeUseWithSyntax<T> ITypeWhenSyntax<T>.When(CanResolveBindingDelegate canResolveBindingDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.When(canResolveBindingDelegate);
            return this;
        }

        #endregion

        #region Implementation of ITypeWithSyntax

        /// <summary>
        /// Use specified constructor argument.
        /// </summary>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="value">The specified parameter value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeWithSyntax.WithConstructorArgument(string name, object value)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WithConstructorArgument(name, value);
            return this;
        }

        /// <summary>
        /// Use specified constructor argument.
        /// </summary>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeWithSyntax.WithConstructorArgument(string name,
                                                                                 ParameterDelegate<object>
                                                                                     parameterDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WithConstructorArgument(name, parameterDelegate);
            return this;
        }


        /// <summary>
        /// Use specified method argument.
        /// </summary>
        /// <param name="methodName">The specified method name.</param>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="value">The specified parameter value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeWithSyntax.WithMethodArgument(string methodName, string name, object value)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WithMethodArgument(methodName, name, value);
            return this;
        }


        /// <summary>
        /// Use specified method argument.
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeWithSyntax.WithMethodArgument(string methodName, string name,
                                                                            ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WithMethodArgument(methodName, name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="name">The specified property name.</param>
        /// <param name="value">The specified property value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeWithSyntax.WithPropertyValue(string name, object value)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WithPropertyValue(name, value);
            return this;
        }


        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="name">The specified property name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeWithSyntax.WithPropertyValue(string name,
                                                                           ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WithPropertyValue(name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified custom argument.
        /// </summary>
        /// <param name="parameter">The specified <see cref="IInjectionParameter"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax ITypeWithSyntax.WithParameter(IInjectionParameter parameter)
        {
            Validate.NotSupportedIfNull(_typeSyntax);
            _typeSyntax.WithParameter(parameter);
            return this;
        }

        #endregion

        #region Implementation of ITypeWithSyntax<T>

#if NOEXPRESSION

        /// <summary>
        /// Use specified constructor argument.
        /// </summary>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="value">The specified parameter value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithConstructorArgument(string name, object value)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithConstructorArgument(name, value);
            return this;
        }

        /// <summary>
        /// Use specified constructor argument.
        /// </summary>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithConstructorArgument(string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithConstructorArgument(name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified method argument.
        /// </summary>
        /// <param name="methodName">The specified method name.</param>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="value">The specified parameter value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithMethodArgument(string methodName, string name, object value)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithMethodArgument(methodName, name, value);
            return this;
        }

        /// <summary>
        /// Use specified method argument.
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="name">The specified parameter name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithMethodArgument(string methodName, string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithMethodArgument(methodName, name, parameterDelegate);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="name">The specified property name.</param>
        /// <param name="value">The specified property value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithPropertyValue(string name, object value)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithPropertyValue(name, value);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="name">The specified property name.</param>
        /// <param name="parameterDelegate">The specified <see cref="ParameterDelegate{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithPropertyValue(string name, ParameterDelegate<object> parameterDelegate)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithPropertyValue(name, parameterDelegate);
            return this;
        }
#else
        /// <summary>
        /// Use specified method arguments.
        /// </summary>
        /// <param name="constructorCall">The specified new instance expression.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithConstructorArguments(Expression<Func<ResolveContext, T>> constructorCall)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithConstructorArguments(constructorCall);
            return this;
        }

        /// <summary>
        /// Use specified propety argument.
        /// </summary>
        /// <param name="property">The property accesss expression.</param>
        /// <param name="value">The specified property value.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithPropertyValue<TValue>(Expression<Func<T, TValue>> property, TValue value)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithPropertyValue(property, value);
            return this;
        }

        /// <summary>
        /// Use specified method arguments.
        /// </summary>
        /// <param name="methodCall">The specified method call expression.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithMethodArguments(Expression<Action<ResolveContext, T>> methodCall)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithMethodArguments(methodCall);
            return this;
        }

#endif
        /// <summary>
        /// Use specified custom argument.
        /// </summary>
        /// <param name="parameter">The specified <see cref="IInjectionParameter"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> ITypeWithSyntax<T>.WithParameter(IInjectionParameter parameter)
        {
            Validate.NotSupportedIfNull(_typeSyntaxGeneric);
            _typeSyntaxGeneric.WithParameter(parameter);
            return this;
        }

        #endregion

    }
}